package com.kool.kmqtt.server.exception;

/**
 * 与MQTT协议不符导致的异常，
 * 需要断开连接的异常
 */
public class ProtocolException extends RuntimeException {

    /**
     * 错误码
     */
    private Integer errorCode;
    /**
     * 错误信息
     */
    private String message;

    public void init(Integer errorCode, String... args) {
        this.errorCode = errorCode;
        this.message = translate(errorCode, args);
    }

    public ProtocolException(Integer errorCode) {
        init(errorCode);
    }

    public ProtocolException(ErrorCode errorCode) {
        init(errorCode.getCode());
    }

    public ProtocolException(Integer errorCode, String... args) {
        init(errorCode, args);
    }

    public ProtocolException(ErrorCode errorCode, String... args) {
        init(errorCode.getCode(), args);
    }

    private void init(Integer errorCode, Exception e, String... args) {
        this.setStackTrace(e.getStackTrace());
        this.errorCode = errorCode;
        this.message = translate(errorCode, args);
    }

    /**
     * 如果是抓取异常后构造AppException异常，则需要传入被抓取的异常，以此保证异常信息的完整
     *
     * @param errorCode
     * @param e
     */
    public ProtocolException(Integer errorCode, Exception e) {
        init(errorCode, e);
    }

    public ProtocolException(ErrorCode errorCode, Exception e) {
        init(errorCode.getCode(), e);
    }

    public ProtocolException(Integer errorCode, Exception e, String... args) {
        init(errorCode, e, args);
    }

    public ProtocolException(ErrorCode errorCode, Exception e, String... args) {
        init(errorCode.getCode(), e, args);
    }

    @Override
    public String getMessage() {
        StringBuilder msg = new StringBuilder();
        if (message != null) {
            msg.append(message);
        }
        return msg.toString();
    }


    public Integer getErrorCode() {
        return this.errorCode;
    }


    /**
     * 翻译错误码。根据错误码从缓存中读取错误码信息
     *
     * @param errorCode
     * @param args
     * @return
     */
    private String translate(Integer errorCode, String[] args) {
        String msg = ErrorCode.getMsgByCode(errorCode);
        if (msg != null && msg.trim().length() > 0) {
            msg = String.format(msg, args);
        }
        return msg;
    }
}
